
/**
 * @author Massimo Bono
 * @date 5 May
 * @file arc.h
 * @brief contiene le strutture e i metodi per la gestione dei singoli elementi Arc
 *
 * Un arco e' semplicemente una connessione tra due nodi. La struttura si pone come obiettivo
 * quello di immagazzinare cio' che la struttura Edge non fa, ossia i vertici che l'arco collega.
 *
 * @see https://code.google.com/p/opt-alg/
 */

#ifndef EDGEID_H_
#define EDGEID_H_

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

#define NO_SHARED_NODE -1

/** Un arco non orientato.
 */
typedef struct EdgeID {
	/** nodo di partenza dell'arco. Il valore deve essere recuperato da una struttura Graph*/
	int i;
	/** nodo di terminazione dell'arco. Il valore deve essere recuperato da una struttura Graph*/
	int j;
} EdgeID;
/** Puntatore di servizio. */
typedef EdgeID* PedgeID;

/**libera la memoria occupata da questa tabu deallocando lo spazio occupato dalla struttura puntata.
 *
 * @param edge l'elemento EdgeID da eliminare
 */
void freeEdgeID(PedgeID edge);

/**costurisce un nuovo elemento EdgeID.
 *
 * \post
 *  \li viene allocata in memoria un novo EdgeID <b>senza</b> controllare se i<j
 *
 * @param _start indica il vertice di inizio dell'arco
 * @param _end indica il vertice di fine dell'arco
 */
PedgeID initEdgeID(short _start,short _end);


/**funzione adatta in fase di testing. Stampa sul file passato come parametro
 * una rappresentazione di un elemento Arc. l'espressione stampata e':
 * <center>(START->END)</center>
 *
 * @param f indica il file su cui scrivere;
 * @param edge indica l'arco da stampare;
 */
void printEdgeID(FILE* f, PedgeID e);

/**per definizione un arco a coincide con un arco b se i nodi coinvolti sono gli stessi. Per esempio queste coppie di archi sono tutte identiche:
 * \li 1--2 1--2
 * \li 1--2 2--1
 *
 * @param arc1 il primo arco da comparare
 * @param arc2 il secondo arco da comparare
 * @return "true" se il campi i e j dei due archi coincidono; "false" altrimenti
 */
bool equals(PedgeID e1, PedgeID e2);

/**verifica che i due archi inseriti siano o meno consecutivi. Due archi sono definiti consecutivi se e solo se:
 * \f[
 * e1_{ab}, e2_{cd} : a=c \vee b=c \vee a=D \vee b=d
 * \f]
 * non e' necessario che i due archi abbiamo i<j (anche se cio' velocizza la funzione)
 *
 * \pre
 *  \li e1 non NULL
 *  \li e2 non NULL
 *
 * @param e1 il primo arco da valutare
 * @param e2 il secondo arco da valutare
 * @return TRUE se i due archi sono consecutivi, FALSE altrimenti
 */
bool areConsecutive(PedgeID e1, PedgeID e2);

/**calcola il nodo comune a 2 edge consecuitutivi
 *
 * \pre
 *  \li e1 non NULL
 *  \li e2 non NULL
 *  \li e1 consecutivo a e2 (usare la funzione areConsecutive )
 *
 * @param e1 un edge
 * @param e2 un edge
 * @return il nodo comune agli edge e1 ed e2
 * @return NO_SHARED_NODE sse non esiste un nodo comune.
 */
int getSharedNode(PedgeID e1,PedgeID e2);

/**verifica se il particolare nodo e' una estremita' dell'arco passato.
 *
 * \pre
 *  \li e non NULL
 *
 * @param e l'arco da verificare
 * @param node il nodo da verificare
 * @return TRUE se il nodo e' una estremita' dell'arco, FALSE altrimenti
 */
bool isNodeUsedByEdgeID(PedgeID e,int node);

/**riassetta l'arco in modo che si verifichi i<j
 *
 * \pre
 *  \li e non NULL
 *
 * \post
 *  \li e non NULL
 *  \li e ha i<j
 *
 * @param e l'arco da confermare
 */
void validateEdgeID(PedgeID e);

/**determina l'altro nodo coinvolto da questo arco
 *
 * \pre
 *  \li e non NULL
 *  \li node e' uno dei due estremi di e
 *
 * @param e l'arco da valutare
 * @param node uno dei due nodi collegati da e
 * @return l'altro nodo collegato da e
 */
int getEdgeIDOtherNode(PedgeID e,int node);


#endif /* EDGEID_H_ */
